en:documentation:script_example

# Script example

This page give tips and example of scripting functions.
You can also look at the three standard tool box code from within the program.
For more details about a specific function see the script reference page.

## Generality

We first look in detail at the code of the Goto button of the Observer tools standard tool box.
This cover many programming basis.

The full script code look as following:

    // Slew telescope
      var ra,de: double;
          a,b,r: string;
          c: Tstringlist;
      begin
      memo_1.clear;
      if MenuTelescopeConnect.checked then begin
        if not StrToAR(Edit_1.text,ra) then begin memo_1.lines.add(rserror+' RA!');exit;end;
        if not StrToDE(Edit_2.text,de) then begin memo_1.lines.add(rserror+' DE!');exit;end;
        a:=floattostr(ra);
        b:=floattostr(de);
        GetSL('STRL1',c);
        c.clear;
        c.add('SLEW');
        c.add(a);
        c.add(b);
        r:=cmd('',c);
        c.clear;
        memo_1.lines.add(r);
      end
      else memo_1.lines.add(rsTelescopeNot);
      end.

Take a look at each part in detail:

    // Slew telescope

Is a comment, you can use // {..} (*..*) to enclose your comments.

      var ra,de: double;
          a,b,r: string;
          c: Tstringlist;

Define the variable we use later in the script.
Important variable type are: integer, double, string.
The Tstringlist type is use here to send a command to Skychart.

      begin

The start of our program.

    memo_1.clear;

Clear the text box we use to show the messages. This ensure the text box is not filled by previous messages.

      if MenuTelescopeConnect.checked then begin

We test the Checked property of the menu item MenuTelescopeConnect. This indicate we have connected the telescope to the program.
If the result is true we execute the code block starting at “begin” up to the corresponding “end”

        if not StrToAR(Edit_1.text,ra) then begin memo_1.lines.add(rserror+' RA!');exit;end;

We try to convert the RA in HMS format from the text in Edit_1 text box to a numeric value. If the conversion fail (because we type some junk in the text box) we show an error message and exit.

       a:=floattostr(ra);

Convert the RA back to string representation but with the decimal format required by the command.

    GetSL('STRL1',c);
    c.clear;

Request a TStringList object identified by STRL1. We clear any data that may stay in the object.

        c.add('SLEW');
        c.add(a);
        c.add(b);

Add the command and the required parameters (in this case RA and DEC) to the stringlist.

       r:=cmd('',c);

Execute the command and store the result in the variable r.

    memo_1.lines.add(r);

Show the result of the command to the text box.

    else memo_1.lines.add(rsTelescopeNot);

The case the test MenuTelescopeConnect.checked is false we execute this line.
It show in the text box a translation in the local language of 'Telescope not connected'.

     end.

The end of the program.

## Call an external library

You can define a function in an external library for use within your script as another local function.

This example implement a simple chronometer by using the GetTickCount function of the Windows API.
There is two button Start and Stop and two text box. A global integer variable is used to store the start time.

Script for the Start button:

     function GetTickCount: Longint; external 'GetTickCount@kernel32.dll stdcall';
     var
       tick: Longint;
     begin
       tick:=GetTickCount;
       setI('Int1',tick);
       edit_1.text:='Started';
     end.

Script for the Stop button:

    function GetTickCount: Longint; external 'GetTickCount@kernel32.dll stdcall';
    var
      t: double;
      t1,tick: Longint;
    begin
      tick:=GetTickCount;
      getI('Int1',t1);
      t:=double(tick-t1)/1000;
      edit_1.text:='';
      edit_2.text:=formatdatetime('HH:MM:SS.ZZZ',t/24/3600);
    end.

You can call any library function this way but beware this is system dependent, the kernel32.dll library is not available on Mac or Linux.

Another limitation is that many library function expect a pointer to a parameter structure. As the script language use byte code internally (as Java) it cannot use a pointer to give the parameters. A solution is to write a C library wrapper that export the function with a flat parameter list.

## Using ASCOM directly

This describe how to use an ASCOM device directly from your script without any use of the Skychart internal ASCOM telescope.

This can be use to access another class of device, the example here connect to a dome, or to access additional properties for your telescope.
In the later case you must be careful that your script work as a concurrent to Skychart main program for the device access.

### Use the ASCOM chooser

The following code assigned to a button allow to select the ASCOM Dome driver we want to use. The driver name is saved in the text field Edit_1.

     var
       V: variant;
       w,s: widestring;
     begin
       V := CreateOleObject('ASCOM.Utilities.Chooser');
       w:='Dome';
       V.DeviceType:=w;
       s:=edit_1.text;
       s:=V.Choose(s);
       edit_1.text:=s;
       V:=Unassigned;
     end.

Replace w:='Dome'; by Telescope, Focuser, Rotator, Camera, Filter to select another driver class.

### Connect to the ASCOM driver

The following code is for the “Connect” button. It connect to the ASCOM Dome driver we select previously. We use the global variable Dome1 to store the ASCOM object.

    var
      D: variant;
      s: widestring;
    begin
      s:=edit_1.text;
      getV('Dome1',D);
      if VarIsEmpty(D) then
        D := CreateOleObject(s);
      D.connected:=true;
      setV('Dome1',D);
    end.

### Use the ASCOM driver

Now we want to add a button to open the dome shutter. This is just an example, at this point any ASCOM property can be use.
The first test protect again a program crash if we try to use an initialized variant.
The second test protect again an ASCOM error if the dome is not connected.

    var
      D: variant;
    begin
      getV('Dome1',D);
      if (not VarIsEmpty(D)) then
        if D.Connected then
           D.OpenShutter;
    end.

### Disconnect the ASCOM driver

Add a button to disconnect the driver and release the resources.

    var
      D: variant;
    begin
      getV('Dome1',D);
      if (not VarIsEmpty(D)) then
        if D.Connected then
           D.connected:=false;
      D:=Unassigned;
      setV('Dome1',D);
    end.

## Open a document

The following code open the Skychart documentation page in the default web browser.
You can use any document type with this function, the document open with the default application the same way as if you double click the document in the file explorer.

    begin
      OpenFile('doc\wiki_doc\en\documentation\start.html');
    end.

## Run a command

There is two different way to run an external command or program, depending if you want to wait for a result or not.

### Wait for a result

The following command run the DIR command in the current directory. The result is stored in a stringlist and later show in a text memo. It contain the list of files in the directory.

    var r:TstringList;
    begin
      GetSL('STRL1',r);
      r.clear;
      RunOutput('dir',r);
      Memo_1.lines.assign(r);
    end.

### No wait

If the command can run for an undetermined time or do not produce an output you need to use the following form.
This example run the Variable star observer program and exit immediately.

    begin
      Run('varobs');
    end.